package be.kuleuven.mume.servlet;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import twitter4j.QueryResult;
import twitter4j.Tweet;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.auth.AccessToken;

import be.kuleuven.mume.TwitterConst;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Text;

public class TwitterCronJob extends HttpServlet{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -4500949181556728704L;
	private static final Logger log = Logger.getLogger(TwitterCronJob.class.getName());
	private static DatastoreService datastore;
	
	public void doGet(HttpServletRequest req, HttpServletResponse resp){
		try{
			
			log.log(Level.WARNING, "TwitterCronJob: Twitter Cron Started");
			datastore = DatastoreServiceFactory.getDatastoreService();
			Query query = new Query("Tweet").addSort("datestamp", Query.SortDirection.DESCENDING);
			List<Entity> tweets = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(1));
			
			long sinceId = Long.parseLong("119719744281640960");
			//String since = "2011-09-15";
			if (!tweets.isEmpty())
			{
				sinceId = Long.parseLong(tweets.get(0).getProperty("guid").toString());
				/*Date d = (Date)tweets.get(0).getProperty("datestamp");
				Calendar c = Calendar.getInstance();
				c.setTime(d);
				since = c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH)+1) + "-" + c.get(Calendar.DAY_OF_MONTH);*/
			}
			
			log.log(Level.WARNING, "TwitterCronJob: Requesting Twitter token1");
			Twitter twitter = TwitterConst.getTwitter();
			log.log(Level.WARNING, "TwitterCronJob: Requesting Twitter token2");
			AccessToken accessToken = TwitterConst.getAccessToken();
			log.log(Level.WARNING, "TwitterCronJob: Requesting Twitter token3");
			twitter.setOAuthAccessToken(accessToken);
			log.log(Level.WARNING, "TwitterCronJob: Requesting Twitter token4");
			
			resp.getWriter().write(storeNewTweets(sinceId,"mume11",twitter));
			resp.getWriter().write(storeNewTweets(sinceId, "thesis11", twitter));
			
		} catch (IOException e) {
			log.log(Level.SEVERE, "IOException", e);
		} catch (Exception e) {
			log.log(Level.SEVERE, "Exception", e);
		}
	}

	public static String storeNewTweets(long since, String hashTag, Twitter twitter) {
		log.log(Level.WARNING, "TwitterCronJob: StoreNewTweets");
		try {
			/*int hits = twitter.getRateLimitStatus().getRemainingHits();
			if(hits < 40) {
				log.log(Level.SEVERE,"TwitterCronJob: Twitter query not executed. RemeiningHits:" + hits);
				return "error";
			}*/
			
			log.log(Level.SEVERE,"TwitterCronJob: Creating query");
			twitter4j.Query q = new twitter4j.Query("%23"+hashTag);
			int results = 0,rpp=0, page = 0;
			do{
				page++;
				q.setPage(page);
				q.setRpp(10);
				results = 0;
				q.setSinceId(since);
				log.log(Level.SEVERE,"TwitterCronJob: Requesting tweets" + since);
				QueryResult qr = twitter.search(q);
				log.log(Level.SEVERE,"TwitterCronJob: Received warning:" + qr.getWarning());
				for (Tweet t : qr.getTweets()) {
					storeTweet(t, hashTag);
					results++;
				}
				rpp = qr.getResultsPerPage();
			} while(rpp == results);
			
			return "succes";
		
		} catch (TwitterException e) {
			log.log(Level.SEVERE, "TwitterException", e);
		}
		return "error";
	}
	
	private static void storeTweet(Tweet t, String hashtag){
		
		log.log(Level.WARNING, "TwitterCronJob: StoreTweet");
		Entity entryEntity = new Entity("Entry");
		entryEntity.setProperty("set", hashtag);
		entryEntity.setProperty("lastmodified", new Date());
		entryEntity.setProperty("guid", t.getId());
		entryEntity.setProperty("datestamp", t.getCreatedAt());
		entryEntity.setProperty("author", t.getFromUser());
		entryEntity.setProperty("text", new Text(t.getText()));
		entryEntity.setProperty("tags", hashtag);
		entryEntity.setProperty("link", "http://twitter.com/#!/" + t.getFromUser() + "/status/" + t.getId());
		entryEntity.setProperty("type", "Tweet");
		entryEntity.setProperty("image", t.getProfileImageUrl());
		datastore.put(entryEntity);


		Entity tweetEntity = new Entity("Tweet");
		tweetEntity.setProperty("set", hashtag);
		tweetEntity.setProperty("lastmodified", new Date());
		tweetEntity.setProperty("guid", t.getId());
		tweetEntity.setProperty("datestamp", t.getCreatedAt());
		tweetEntity.setProperty("author", t.getFromUser());
		tweetEntity.setProperty("text", new Text(t.getText()));
		// TODO: extract hashtags from text
		tweetEntity.setProperty("tags", hashtag);
		tweetEntity.setProperty("link", "http://twitter.com/#!/" + t.getFromUser() + "/status/" + t.getId());
		tweetEntity.setProperty("isolanguagecode", t.getIsoLanguageCode() );
		if (!"".equals(t.getToUser()))
			tweetEntity.setProperty("to", t.getToUser());
		entryEntity.setProperty("image", t.getProfileImageUrl());
		datastore.put(tweetEntity);
	}

}
